home *** CD-ROM | disk | FTP | other *** search
- /* This program should take a .t64 file and pull it apart into */
- /* the original, separate CBM files. */
- /* Version 1.2 */
-
- /* Written by pbhoeffl@undergrad.math.uwaterloo.ca */
- /* on March 26-7, 1994 */
-
- /* Modified by pbhoeff@io.org */
- /* February 16, 1995 */
-
- /* - Wouldn't you know it that the .t64's I tested all had one thing in */
- /* common... the filesizes given in the header were correct. The day */
- /* after I put this up on Watson, I found out that there were lots of */
- /* files for which this was *not* true. Hopefully, this version does */
- /* not invite the guru like the old version did. */
-
- /* - A KingCON user pointed this out to me: UnT didn't strip off trailing */
- /* spaces from the archive name specified on the command line. This */
- /* meant that if you typed "UnT WickedGame.T64 " it would look for (and */
- /* not find) "WickedGame.T64 " with that trailing space in the name. */
-
- /* I received only a very small number of email's concerning UnT (true, I */
- /* solicited none), so either: */
- /* a) nobody used it, */
- /* b) people used it, ran into all the above bugs, and tossed it, */
- /* c) people used it, luckily missed all the bugs, and are happy. */
- /* I wrote UnT primarily for myself so, lack of demand aside, it is for my */
- /* own peace of mind that I am implementing these fixes. */
-
- /* Development Suite: */
- /* Hardware: A500 KS1.3 OCS */
- /* Software: WB 1.3, Amiga E v2.1b, Vim 2.0 & 3.0 */
-
- /* I maintain no copyright on this program, and hereby release */
- /* it into the public domain. If I am violating someone elses */
- /* copyright by releasing this as such... well, I guess that's */
- /* my tough luck. */
-
-
-
- ENUM NOARG, NOARCHIVE, EMPTYARCHIVE, NOMEMORY, READERROR
- ENUM CANTCREATE, WRITEERROR
-
-
- DEF flen, handle=NIL, mem
-
- PROC main () HANDLE
- DEF i, j, numFiles, numUsed, prompt[16]:STRING, archname[127]:STRING
-
- WriteF (' \e[3mUnT Version 1.2 \e[0m\n')
-
- StrCopy (archname, TrimStr (arg), ALL)
- j := StrLen (archname)
- WHILE (archname[j-1] = " ") AND (j > 0)
- j := j-1
- ENDWHILE
- SetStr (archname, j)
-
- IF StrLen (archname) = 0 THEN Raise (NOARG)
- /* WriteF ('Archive is: \s\n', archname) */
-
- handle := Open (archname, OLDFILE)
- IF handle = NIL THEN Raise (NOARCHIVE)
- flen := FileLength (archname)
- IF flen < 1 THEN Raise (EMPTYARCHIVE)
- /* WriteF ('Located \s. Size=\d\n', archname, flen) */
-
- mem := New (flen)
- IF mem = NIL THEN Raise (NOMEMORY)
- /* WriteF ('Memory successfully allocated.\n') */
-
- IF Read (handle, mem, flen) <> flen THEN Raise (READERROR)
- /* WriteF ('Read archive successfully.\n', archname) */
-
- /* We're done with the archive file */
- Close (handle); handle := NIL
-
- WriteF ('User Description : ')
- print_text (40, 24); WriteF ('\n')
-
- /*
- WriteF ('DOS Description :\n')
- print_text (0, 32); WriteF ('\n')
- */
-
- numFiles := make_int16 (34)
- WriteF ('Number of Entries: \d\n', numFiles)
- numUsed := make_int16 (36)
- WriteF ('Number Used : \d\n', numUsed)
-
- WriteF ('\nScanning Tape-Archive...\n')
- FOR i := 0 TO numFiles-1
- IF mem[64+(i*32)] = 1
- WriteF ('#\d ', i)
- print_entry (64+(i*32))
- ENDIF
- ENDFOR
- WriteF ('Done\n\n')
-
- IF numUsed = 0
- WriteF ('According to the header info, there are no files in this archive.\n')
- WriteF ('This is probably bogus. The first entry is likely the converted file.\n\n')
-
- print_entry (64)
-
- WriteF ('Do you wish to extract this file (Y/N)? ')
- ReadStr (stdout, prompt); UpperStr (prompt)
-
- IF prompt[0] = "Y"
- WriteF ('Type the name you wish to give to this file:\n')
- ReadStr (stdout, prompt)
-
- IF StrLen (prompt) > 0
- extract_file (64, prompt)
- ENDIF
- ENDIF
- ELSE
- FOR i := 0 TO numFiles-1
- IF mem[64+(i*32)] = 1
- /* Pull & trim the filename from the directory entry */
- j := 16
- WHILE (mem[(64+(i*32)) + 16 + j - 1] = " ") AND (j >= 0)
- j := j-1
- ENDWHILE
- SetStr (prompt, j)
- StrCopy (prompt, mem + (64+(i*32)) + 16, j)
-
- extract_file (64+(i*32), prompt)
- ENDIF
- ENDFOR
- ENDIF
-
-
- CleanUp(0)
-
-
- /* Error conditions */
-
- EXCEPT
- SELECT exception
- CASE NOARG
- WriteF ('Usage: UnT <archive.t64>\n')
- CASE NOARCHIVE
- WriteF ('Unable to open \s!\n', archname)
- CASE EMPTYARCHIVE
- WriteF ('Archive \s is EMPTY!\n', archname)
- CASE NOMEMORY
- WriteF ('Could not allocate enough memory.\n')
- CASE READERROR
- WriteF ('Read Error on \s.\n', archname)
- DEFAULT
- WriteF ('BAD SCENE, MAN!!!\n')
- ENDSELECT
- Close (handle)
- CleanUp (-1)
- ENDPROC
-
-
-
- PROC print_text (start, length)
- DEF s[80]:STRING
-
- SetStr (s, length)
- StrCopy (s, mem+start, length)
- WriteF ('\e[40;33m\s\e[40;31m', s)
-
- ENDPROC
-
-
-
- PROC print_entry (rec_base)
- DEF fileType, fileStart, fileEnd
-
- fileType := mem[rec_base + 1]
- SELECT fileType
- CASE 1
- WriteF ('PRG "')
- CASE 68
- WriteF ('PRG "')
- /* RE: other CASEs would be implemented if I had my 1541 manual here. */
- /* I have now been re-united with my 1541 manual, only to realize */
- /* that these .t64 filetypes don't correspond to the CBM filetypes. */
- /* Oh, well. It was only cosmetic anyways. */
- DEFAULT
- WriteF ('??? "')
- ENDSELECT
-
- print_text (rec_base + 16, 16)
-
- fileStart := make_int16 (rec_base + 2)
- fileEnd := make_int16 (rec_base + 4)
-
- WriteF ('" Start=$\z\h[4] ', fileStart)
- WriteF ('End=$\z\h[4]\n', fileEnd)
-
- /* Note: make_int16(rec_base+8) may cause problems with tapes
- larger than 64K... it's really supposed to be an int32.
- */
- IF (fileEnd - fileStart) > (flen - make_int16 (rec_base + 8))
- WriteF (' WARNING!! Reported file length is greater than archive length!\n')
- ENDIF
- ENDPROC
-
-
-
- PROC extract_file (rec_base, name) HANDLE
- DEF length, i, fileStart, fileEnd
-
- WriteF ('Extracting "\s"', name)
- fileStart := make_int16 (rec_base + 2)
- fileEnd := make_int16 (rec_base + 4)
- length := fileEnd - fileStart
-
- IF length > (flen - make_int16 (rec_base + 8))
- length := (flen - make_int16 (rec_base + 8))
- WriteF (' (End=$\z\h[4])', fileStart + length)
- ENDIF
-
- WriteF ('...')
-
- handle := Open (name, NEWFILE)
- IF handle = NIL THEN Raise (CANTCREATE)
-
- i := Write (handle, (mem + rec_base + 2), 2)
- IF i <> 2 THEN Raise (WRITEERROR)
- i := Write (handle, (mem + make_int16 (rec_base + 8)), length)
- IF i <> length THEN Raise (WRITEERROR)
-
- Close (handle)
- WriteF (' OK\n')
-
- EXCEPT
- SELECT exception
- CASE CANTCREATE
- WriteF ('Unable to create file!\n')
- CASE WRITEERROR
- WriteF ('Write Error!\n')
- DEFAULT
- WriteF ('BAD SCENE, MAN!!!\n')
- ENDSELECT
- Close (handle)
- CleanUp (-1)
- ENDPROC
-
-
-
- PROC make_int16 (address)
- RETURN ( mem[address] + (256 * mem[address+1]) )
- ENDPROC
-